﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Windows.Forms;

namespace Swsk33.Test.Plugin.Main
{
	public partial class MainGUI : Form
	{
		/// <summary>
		/// 记录插件名及其对应的插件类实例的映射表
		/// </summary>
		private Dictionary<string, object> pluginNames = new Dictionary<string, object>();

		public MainGUI()
		{
			InitializeComponent();
		}

		private void MainGUI_Load(object sender, EventArgs e)
		{
			// 在load事件中加载插件，搜索程序自身所在目录下的plugins文件夹中的dll插件
			string[] pluginFilepath = Directory.GetFiles(Directory.GetCurrentDirectory() + "\\plugins", "*.dll");
			// 遍历dll文件并获取其中的类
			foreach(string dllPath in pluginFilepath)
			{
				// 先获取dll的程序集
				Assembly assembly = Assembly.LoadFrom(dllPath);
				// 获取这个dll中所有的类
				Type[] types = assembly.GetTypes();
				foreach(Type type in types)
				{
					// 判断这个类是否实现了插件对应的插件模板接口，若没有说明该插件无效，实现了则加入到插件列表
					if (type.GetInterface("IPlugin") != null && type.GetInterface("IPlugin").FullName.Equals("Swsk33.Test.Plugin.Interface.IPlugin"))
					{
						// 利用反射获取插件类的插件名属性
						PropertyInfo pluginName = type.GetProperty("Name");
						// 实例化插件中的类
						object pluginInstance = assembly.CreateInstance(type.FullName);
						// 利用反射获取插件名
						string name = (string)pluginName.GetValue(pluginInstance);
						// 加入到映射表，键是插件名，值是插件中实现类的实例
						pluginNames.Add(name, pluginInstance);
					}
				}
			}
			// 最后，把映射表插件名加入到listbox里面
			foreach(string pluginName in pluginNames.Keys)
			{
				mainListBox.Items.Add(pluginName);
			}
		}

		private void showText_Click(object sender, EventArgs e)
		{
			if (mainListBox.SelectedIndex != -1)
			{
				// 根据listbox选中值，从映射表中取出插件实例
				object pluginInstance = pluginNames[mainListBox.SelectedItem.ToString()];
				// 利用反射先获取其中的GetText方法
				MethodInfo method = pluginInstance.GetType().GetMethod("GetText");
				// 利用反射执行该实例的方法
				string result = (string)method.Invoke(pluginInstance, null);
				// 显示
				pluginText.Text = result;
			}
		}
	}
}